<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17.2.2-带有 v-for 指令的节点</title>
</head>
<body>
    <!-- 参考例子 1 -->
    <div>
        <p v-for="item in list">{{ item }}</p>
        <i>{{ foo }}</i>
        <i>{{ bar }}</i>
    </div>

</body>
    <script>
        /**
         * 带有 v-for 指令的节点也会让虚拟 DOM 树变得不稳定
         * 
         * 传统 Diff 的一个非常重要的前置条件是：
         *  - 进行 Diff 操作的节点必须是同层级节点。
         *  - 但是 dynamicChildren 数组内的节点未必是同层级的
         * 
         * 解决方法
         * - 只需要让带有 v-for 指令的标签也作为Block 角色即可
         * 
        */

        /**
         * 参考例子 1
         * list 数组的值由 [1 ,2] 变为 [1], 
         * - 按照之前的思路，即只有根节点会作为 Block 角色
         * - 只有最外层的 <div> 标签会作为 Block
         * */  
        // 更新前
        const prevBlock = {
            tag: 'div',
            dynamicChildren: [
                { tag: 'p', children: 1,  /* TEXT */ },
                { tag: 'p', children: 2,  /* TEXT */ },
                { tag: 'i', children: ctx.foo,  /* TEXT */ },
                { tag: 'i', children: ctx.bar,  /* TEXT */ },
            ]
        }
        // 更新后
        const nextBlock = {
            tag: 'div',
            dynamicChildren: [
                { tag: 'p', children: item,    /* TEXT */ },
                { tag: 'i', children: ctx.foo, /* TEXT */ },
                { tag: 'i', children: ctx.bar, /* TEXT */ },
            ]
        }

        /**
         * v-for 指令渲染的是一个片段，
         *  所以我们需要使用类型为 Fragment 的节点来表达 v-for 指令的渲染结果，
         *  并作为 Block 角色
         * 
        */

        const block = {
            tag: 'div',
            dynamicChildren: [
                // 这是一个 Block，它有 dynamicChildren
                { tag: Fragment, dynamicChildren: [/* v-for 的节点 */] },
                { tag: 'i', children: ctx.foo,  /* TEXT */ },
                { tag: 'i', children: ctx.bar,  /* TEXT */ },
            ]
        }
         

    </script>
</html>